import React, { FunctionComponent } from "react";
import { useLocation, useRouteMatch } from "react-router";
import { BrowserRouter, Route, Redirect, Switch } from "react-router-dom";
import { useClientLanguage, useAppContainerManager } from "@anyshare/common/lib/hooks";
import { languages } from "@anyshare/common/lib/constants";
import {
    IntlProvider,
    EventBusProvider,
    LanguageProvider,
    AuthProvider,
    AppManagerProvider,
    AppContainerManagerProvider,
    AppActivator,
    ConfigProvider,
    AntdConfigProvider,
    FileHandlerProvider,
    IconThemeProvider,
    DialogAppContainer,
    DrawerAppContainer,
    ToastProvider,
    HandleActivityProvider,
} from "@anyshare/components";
import { MicroWidgetProvider, FrameSdkProvider } from "@anyshare/microwidget";
import { ContextMenuProvider } from "@anyshare/controls";
import IndexPage from "./pages/IndexPage";
import AppPage from "./pages/AppPage";
import NotFoundPage from "./pages/NotFoundPage";
import openapi from "@anyshare/openapi";
import {
    copy,
    dir,
    messagebox,
    move,
    select,
    settings,
    download,
    applist,
    sharereview,
    shareapply,
    flowreview,
    flowapply,
    securityreview,
    securityapply,
    recycle,
    quaratine,
    message,
    filelock,
    contact,
    device,
    size,
    newdir,
    rename,
    search,
    foxitreader,
    share,
    metadata,
    tags,
    remove,
    summary,
    securitylevel,
    version,
    sendmail,
    approvaltips,
    shareapplytips,
    accessoradded,
    fileflow,
    link,
    copysharedlink,
    saveas,
    previewimg,
    play,
    privacyinfo,
    officeonline,
    cadpreview,
    smartsearch,
    filebrowselist,
    dragmove,
    location,
    webfoxitreader,
    crossdomain,
    crosssync,
    crosslist,
    crossgoing,
    wpspreview,
    opendir,
    microWidgets,
    microWidgetsForTaskBar,
    microWidgetsDialog,
    knowledgeDoc,
    microWidgetsFullScreen,
} from "@anyshare/apps";
import { useObserver } from "mobx-react-lite";

Object.assign(window, { openapi });

declare const __ANYSHARE_EXTENSIONS__: any;

const apps = [
    ...(__ANYSHARE_EXTENSIONS__ || []),
    copy,
    dir,
    messagebox,
    move,
    select,
    settings,
    applist,
    sharereview,
    shareapply,
    flowreview,
    flowapply,
    securityreview,
    securityapply,
    recycle,
    quaratine,
    message,
    filelock,
    contact,
    device,
    size,
    newdir,
    rename,
    search,
    foxitreader,
    share,
    metadata,
    tags,
    remove,
    download,
    summary,
    securitylevel,
    version,
    sendmail,
    approvaltips,
    shareapplytips,
    accessoradded,
    fileflow,
    link,
    copysharedlink,
    saveas,
    previewimg,
    play,
    privacyinfo,
    officeonline,
    cadpreview,
    smartsearch,
    filebrowselist,
    dragmove,
    location,
    webfoxitreader,
    crossdomain,
    crosssync,
    crosslist,
    crossgoing,
    wpspreview,
    opendir,
    microWidgets,
    microWidgetsForTaskBar,
    microWidgetsDialog,
    knowledgeDoc,
    microWidgetsFullScreen,
];

const DrawerAndDialogContainers = () => {
    const appContainerManager = useAppContainerManager();

    return useObserver(() => (
        <>
            {appContainerManager.containers.map((container) => {
                switch (container.type) {
                    case "dialog":
                        return <DialogAppContainer key={container.id} container={container} />;
                    case "drawer":
                        return <DrawerAppContainer key={container.id} container={container} />;
                    default:
                        return null;
                }
            })}
        </>
    ));
};

const Main = () => {
    const { path } = useRouteMatch();
    const { pathname } = useLocation();
    const pathlength = pathname.split("/").filter((item) => {
        return item !== "";
    }).length;
    let setNotFound = false;
    if (pathlength !== 1) {
        if (
            !apps
                .filter((app) => {
                    return app.views;
                })
                .map((app) => app.name)
                .includes(
                    pathname.split("/").filter((item) => {
                        return item !== "";
                    })[1]
                )
        ) {
            setNotFound = true;
        }
    }

    return (
        <EventBusProvider>
            <LanguageProvider>
                <AppManagerProvider apps={apps}>
                    <AppContainerManagerProvider>
                        <AntdConfigProvider>
                            <IntlProvider>
                                <AppActivator />
                                <IconThemeProvider>
                                    <FileHandlerProvider>
                                        <AuthProvider>
                                            <ConfigProvider>
                                                <ToastProvider>
                                                    <ContextMenuProvider>
                                                        <MicroWidgetProvider>
                                                            <FrameSdkProvider>
                                                                <HandleActivityProvider>
                                                                    <Switch>
                                                                        {setNotFound ? (
                                                                            <Route path="*" component={NotFoundPage} />
                                                                        ) : null}
                                                                        <Route
                                                                            path={`${path}/:app/:slash*`}
                                                                            component={AppPage}
                                                                        />
                                                                        <Route path={path} component={IndexPage} />
                                                                    </Switch>
                                                                    <DrawerAndDialogContainers />
                                                                </HandleActivityProvider>
                                                            </FrameSdkProvider>
                                                        </MicroWidgetProvider>
                                                    </ContextMenuProvider>
                                                </ToastProvider>
                                            </ConfigProvider>
                                        </AuthProvider>
                                    </FileHandlerProvider>
                                </IconThemeProvider>
                            </IntlProvider>
                        </AntdConfigProvider>
                    </AppContainerManagerProvider>
                </AppManagerProvider>
            </LanguageProvider>
        </EventBusProvider>
    );
};

const Routes = () => {
    const { pathname, search } = useLocation();
    const clientLanguage = useClientLanguage();

    return (
        <Switch>
            <Route path={`/(zh-cn|zh-tw|en-us)`} component={Main} />
            <Redirect
                from={`/(${languages.join("|")})`}
                to={{
                    pathname: `/${
                        clientLanguage === "zh-hk" || clientLanguage === "zh-tw"
                            ? "zh-tw"
                            : clientLanguage.startsWith("zh")
                            ? "zh-cn"
                            : "en-us"
                    }${pathname.slice(`/${clientLanguage}`.length)}`,
                    search,
                }}
            />
            <Redirect from="*" to={{ pathname: `/${clientLanguage}${pathname}`, search }} />
        </Switch>
    );
};

const App: FunctionComponent = () => {
    return (
        <BrowserRouter basename="/anyshare">
            <Routes />
        </BrowserRouter>
    );
};

export default App;
